package com.ibeeking.found.upms.g.rest.service.impl;

import com.ibeeking.found.common.entity.CurrentUser;
import com.ibeeking.found.upms.g.rest.service.IGmcRolePermissionService;
import com.ibeeking.found.upms.g.rest.service.IGmcUserRoleService;
import com.ibeeking.found.upms.service.common.bo.RolePermissionBO;
import com.ibeeking.found.upms.service.common.bo.GmcUserRoleBO;
import com.ibeeking.found.upms.service.common.dos.RolePermissionDO;
import com.ibeeking.found.upms.service.common.param.PermissionRoleParam;
import com.ibeeking.found.upms.service.common.param.RolePermissionParam;
import com.ibeeking.found.upms.service.mapper.RolePermissionMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @project: GmcRolePermissionServiceImpl
 * @description: 角色权限接口实现类
 * @Author ibeeking
 * @create: 2020-12-05 15:19:57
 **/
@Service
public class GmcRolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermissionDO> implements IGmcRolePermissionService {

    @Resource
    private RolePermissionMapper rolePermissionMapper;
    @Resource
    private IGmcUserRoleService userRoleServiceImpl;

    @Override
    public List<RolePermissionBO> queryRolePermissionByRoleIds(List<Long> roleIds) {
        List<RolePermissionDO> rolePermissionDos = rolePermissionMapper.selectList(new LambdaQueryWrapper<>(RolePermissionDO.class).in(RolePermissionDO::getRoleId, roleIds));
        if (Collections3.isEmpty(rolePermissionDos)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(rolePermissionDos, RolePermissionBO.class);
    }

    @Override
    public List<RolePermissionBO> queryRolePermissionByRoleId(Long roleId) {
        List<RolePermissionDO> rolePermissionDOS = rolePermissionMapper.selectList(new LambdaQueryWrapper<>(RolePermissionDO.class).eq(RolePermissionDO::getRoleId, roleId));
        if (Collections3.isEmpty(rolePermissionDOS)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(rolePermissionDOS, RolePermissionBO.class);
    }

    @Override
    public List<RolePermissionBO> queryRolePermissionByPermissionId(Long permissionId) {
        List<RolePermissionDO> rolePermissionDOS = rolePermissionMapper.selectList(new LambdaQueryWrapper<>(RolePermissionDO.class).eq(RolePermissionDO::getPermissionId, permissionId));
        if (Collections3.isEmpty(rolePermissionDOS)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(rolePermissionDOS, RolePermissionBO.class);
    }

    @Transactional(rollbackFor = {BusinessException.class})
    @Override
    public Boolean modifyRolePermissionByRoleId(CurrentUser currentUser, RolePermissionParam rolePermissionParam) {
        // 1. 查询现有角色权限关系
        List<RolePermissionDO> haves = Optional
                .ofNullable(rolePermissionMapper.selectList(new LambdaQueryWrapper<>(RolePermissionDO.class)
                        .eq(RolePermissionDO::getRoleId, rolePermissionParam.getRoleId()))
                ).orElse(Collections3.emptyList());
        //查询当前操作人拥有的权限
        List<GmcUserRoleBO> gmcUserRoleBOS = userRoleServiceImpl.queryUserRoleByUserId(currentUser.getId());
        List<Long> operators = Collections3.emptyList();
        if (!Collections3.isEmpty(gmcUserRoleBOS)) {
            List<RolePermissionDO> rolePermissionDOS = rolePermissionMapper.selectList(new LambdaQueryWrapper<>(RolePermissionDO.class).in(RolePermissionDO::getRoleId, gmcUserRoleBOS.parallelStream().map(GmcUserRoleBO::getRoleId).collect(Collectors.toList())));
            if (!Collections3.isEmpty(rolePermissionDOS)) {
                operators = rolePermissionDOS.parallelStream().map(RolePermissionDO::getPermissionId).collect(Collectors.toList());
            }
        }

        //过滤出可修改的权限
        List<Long> currentIds = Optional.ofNullable(Collections3.intersection(haves.parallelStream().map(RolePermissionDO::getPermissionId).collect(Collectors.toList()), operators)).orElse(Collections3.emptyList());
        if (null == rolePermissionParam.getPermissionIds() || 0 == rolePermissionParam.getPermissionIds().length) {
            if (Collections3.isEmpty(currentIds)) {
                return true;
            } else {
                return rolePermissionMapper.delete(new LambdaQueryWrapper<>(RolePermissionDO.class).eq(RolePermissionDO::getRoleId, rolePermissionParam.getRoleId()).in(RolePermissionDO::getPermissionId, currentIds)) > 0;
            }
        }
        List<Long> paramIds = Arrays.asList(rolePermissionParam.getPermissionIds());
        List<Long> dels = new ArrayList<>();
        List<Long> saveIds = new ArrayList<>();
        if (!Collections3.isEmpty(currentIds)) {
            // 2。 进行取差集
            List<Long> difference = Collections3.difference(currentIds, paramIds);
            if (!Collections3.isEmpty(difference)) {
                dels.addAll(haves.parallelStream().filter(rolePermissionDO -> difference.contains(rolePermissionDO.getPermissionId())).map(RolePermissionDO::getId).collect(Collectors.toList()));
            }
            saveIds.addAll(Collections3.difference(paramIds, currentIds));
        } else {
            saveIds.addAll(paramIds);
        }

        // 删除不存在的关系
        if (!Collections3.isEmpty(dels)) {
            rolePermissionMapper.deleteBatchIds(dels);
        }

        List<RolePermissionDO> saves = new ArrayList<>();
        if (Collections3.isEmpty(saveIds)) {
            return true;
        } else {
            saveIds.parallelStream().forEach(key -> {
                RolePermissionDO rolePermissionDO = new RolePermissionDO();
                rolePermissionDO.setRoleId(rolePermissionParam.getRoleId());
                rolePermissionDO.setPermissionId(key);
                rolePermissionDO.setDelStatus(0);
                saves.add(rolePermissionDO);
            });
        }
        // 新增关系
        rolePermissionMapper.insertBatchSomeColumn(saves);
        return true;
    }

    @Transactional(rollbackFor = {BusinessException.class})
    @Override
    public Boolean modifyRolePermissionByPermissionId(CurrentUser currentUser, PermissionRoleParam permissionRoleParam) {
        // 1. 查询现有角色权限关系
        List<RolePermissionDO> haves = Optional
                .ofNullable(rolePermissionMapper.selectList(new LambdaQueryWrapper<>(RolePermissionDO.class)
                        .eq(RolePermissionDO::getPermissionId, permissionRoleParam.getPermissionId()))
                ).orElse(Collections3.emptyList());
        //查询当前操作人拥有的权限
        List<GmcUserRoleBO> operators = Optional.ofNullable(userRoleServiceImpl.queryUserRoleByUserId(currentUser.getId())).orElse(Collections3.emptyList());
        //过滤出可修改的权限
        List<Long> currentIds = Optional.ofNullable(Collections3.intersection(haves.parallelStream().map(RolePermissionDO::getRoleId).collect(Collectors.toList()), operators.parallelStream().map(GmcUserRoleBO::getRoleId).collect(Collectors.toList()))).orElse(Collections3.emptyList());
        if (null == permissionRoleParam.getRoleIds() || 0 == permissionRoleParam.getRoleIds().length) {
            if (Collections3.isEmpty(currentIds)) {
                return true;
            } else {
                return rolePermissionMapper.delete(new LambdaQueryWrapper<>(RolePermissionDO.class).eq(RolePermissionDO::getPermissionId, permissionRoleParam.getPermissionId()).in(RolePermissionDO::getRoleId, currentIds)) > 0;
            }
        }
        List<Long> paramIds = Arrays.asList(permissionRoleParam.getRoleIds());
        List<Long> dels = new ArrayList<>();
        List<Long> saveIds = new ArrayList<>();
        if (!Collections3.isEmpty(currentIds)) {
            // 2。 进行取差集
            List<Long> difference = Collections3.difference(currentIds, paramIds);
            if (!Collections3.isEmpty(difference)) {
                dels.addAll(haves.parallelStream().filter(rolePermissionDO -> difference.contains(rolePermissionDO.getRoleId())).map(RolePermissionDO::getId).collect(Collectors.toList()));
            }
            saveIds.addAll(Collections3.difference(paramIds, currentIds));
        } else {
            saveIds.addAll(paramIds);
        }

        // 删除不存在的关系
        if (!Collections3.isEmpty(dels)) {
            rolePermissionMapper.deleteBatchIds(dels);
        }

        List<RolePermissionDO> saves = new ArrayList<>();
        if (Collections3.isEmpty(saveIds)) {
            return true;
        } else {
            saveIds.parallelStream().forEach(key -> {
                RolePermissionDO rolePermissionDO = new RolePermissionDO();
                rolePermissionDO.setRoleId(key);
                rolePermissionDO.setPermissionId(permissionRoleParam.getPermissionId());
                rolePermissionDO.setDelStatus(0);
                saves.add(rolePermissionDO);
            });
        }
        // 新增关系
        rolePermissionMapper.insertBatchSomeColumn(saves);
        return true;
    }
}
